//
// Created on 2024/8/26.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef AVCODECSAMPLE_OPENGL_EGL_RENDER_CONTEXT_H
#define AVCODECSAMPLE_OPENGL_EGL_RENDER_CONTEXT_H

// 1. 先包含OpenGL ES核心头文件（定义基础类型）
#include <GLES3/gl3.h>    // GLES3核心头文件，定义GLenum、GLuint等
// 2. 再包含扩展头文件（依赖核心类型）
#include <GLES2/gl2ext.h> // 扩展头文件，此时能识别核心类型
// 3. 最后包含EGL相关头文件（不影响OpenGL类型）
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <cstring>
#include <hilog/log.h>
#include <native_window/external_window.h>
#include <window_manager/oh_window_comm.h>

namespace HarmonyVideoEditorRender {
class EglRenderContext {
public:
    EglRenderContext();
    ~EglRenderContext() noexcept;

    EglRenderContext(const EglRenderContext &) = delete;
    EglRenderContext(const EglRenderContext &&) = delete;
    EglRenderContext &operator=(const EglRenderContext &other) = delete;
    EglRenderContext &operator=(EglRenderContext &&) = delete;
    void operator==(const EglRenderContext &&) = delete;
    void operator==(const EglRenderContext &) = delete;

    bool Init();
    bool IsEglContextReady() const { return eglContext_ != EGL_NO_CONTEXT; }

    EGLDisplay GetEGLDisplay() const { return eglDisplay_; }
    EGLDisplay GetEGLContext() const { return eglContext_; }

    EGLSurface CreateEglSurface(OHNativeWindow *surface, const EGLint *attribList = nullptr);
    void DestroyEglSurface(EGLSurface surface);

    void MakeCurrent(EGLSurface surface) const;
    void SwapBuffers(EGLSurface surface) const;

    // 局部刷新可选接口
    EGLint QueryBufferAge(EGLSurface surface) const;
    void SetDamageRegion(EGLSurface surface, EGLint *damages, EGLint size);
    void SwapBuffersWithDamage(EGLSurface surface, const EGLint *damages, EGLint size);
    bool SetPresentationTime(EGLSurface surface, EGLnsecsANDROID time);

protected:
    EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
    EGLDisplay eglContext_ = EGL_NO_CONTEXT;
    EGLDisplay eglShareContext_ = EGL_NO_CONTEXT;
    EGLConfig config_ = nullptr;

    bool hasEglSurfacelessContext_ = false;
    bool hasEglBufferAge_ = false;
    bool hasEglPartialUpdate_ = false;
    PFNEGLSETDAMAGEREGIONKHRPROC eglSetDamageRegionFunc_ = nullptr;
    PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC eglSwapBuffersWithDamageFunc_ = nullptr;
    PFNEGLCREATEIMAGEKHRPROC eglCreateImageFunc_ = nullptr;
    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2DOESFunc_ = nullptr;

private:
    void SetupEglExtensions();
    void SetupGlExtensions() const;
};
} // namespace HarmonyVideoEditorRender

#endif // AVCODECSAMPLE_OPENGL_EGL_RENDER_CONTEXT_H
